<%@ Page Language="C#" MasterPageFile="~/MasterPages/Learning.Master" AutoEventWireup="true" CodeBehind="ModelViewPresenter.aspx.cs" Inherits="Mindscape.BackgroundMotion.Website.Learn.ModelViewPresenter" Title="Code: Learn about the Model View Presenter pattern" %>
<asp:Content ID="Content3" ContentPlaceHolderID="BodyContent" runat="server">

    <h2>Model View Presenter</h2>
    
    <p>
        <i>"Factor the UI into a view and controller where the view handles simple mapping to the underlying model and the controller handles input response and complex view logic."</i><br />
        <a href="http://www.martinfowler.com/eaaDev/SupervisingPresenter.html">Martin Fowler</a><br />
        <br />
        Model View Presenter, or MVP for short is a presentation pattern which aids in structuring your system to allow for good separation of concerns between the presentation markup and the user interface flow logic.
        <br /><br />
        On BackgroundMotion we used the MVP pattern by extending the prescribed approach in the <a href="WebClientSoftwareFactory.aspx">Composite Web Block</a> to structure our code to promote <a href="UnitTesting.aspx">testability</a> and good separation of concerns.
    </p>
    
    <br />
    <div align="center">
        <a href="/Learn/PlayVideo.aspx?v=Nugget5" target="page" onClick="window.open('','page','toolbar=0,scrollbars=0,location=0,statusbar=0,menubar=0,resizable=0,width=450,height=350,titlebar=yes')"><img border="0" src="/Images/Dev/VideoNugget5.jpg" /></a><br />
        <p>Andrew describes how we used the Model View Presenter pattern</p>    
    </div>
    <br />
    
    <h2>How it works</h2>
    
    <p>
    MVP is implemented by creating a <b>Domain Model</b>, a number of <b>Views</b> and a number of <b>Presenters</b>. In BackgroundMotion our Domain Model is represented in the <b>Model project</b>, the Views are the ASP.NET <b>.aspx</b> pages, the Presenters are classes living in the Mindscape.BackgroundMotion.Website.Views namespace.
    </p>
    
    <h2>Lifecycle of a Request</h2>
    
    <p>
    To help understand further, let's look at what happens when a request to fetch a contribution on the View.aspx page is executed.
    </p>
    
    <h3>Step 1:</h3>
    
    <br />
    <div align="center">
        <img border="0" src="/Images/Dev/MVPa.jpg" /><br />
        <p>A web request is processed against <b>View.aspx</b> as per normal</p>    
    </div>
    <br />
    
    <h3>Step 2:</h3>
    
    <p>
    The Presenter will respond to the OnLoad event for the Page. This has been wired up through the <b>PageBase</b> class.
    </p>
            
    <div style="font-family: Consolas, Verdana; font-size: 11pt; color: black; background: white;">
    <p style="margin: 0px;">&nbsp;</p>
    <p style="margin: 0px;">&nbsp; &nbsp; &nbsp; <span style="color: blue;">if</span> (!IsPostBack)</p>
    <p style="margin: 0px;">&nbsp; &nbsp; &nbsp; {</p>
    <p style="margin: 0px;">&nbsp; &nbsp; &nbsp; &nbsp; _presenter.OnViewInitialized();</p>
    <p style="margin: 0px;">&nbsp; &nbsp; &nbsp; }</p>
    <p style="margin: 0px;">&nbsp;</p>
    <p style="margin: 0px;">&nbsp; &nbsp; &nbsp; <b><span style="color: Red">_presenter.OnViewLoaded();</span></b></p>
    <p style="margin: 0px;">&nbsp; &nbsp; }</p>
    </div>

    <br />
    <br />
    <div align="center">
        <img border="0" src="/Images/Dev/MVPb.jpg" /><br />
        <p>The <b>Presenter</b> wires up and responds to the OnLoad event</p>    
    </div>
    <br />
    
    <h3>Step 3:</h3>
    
    <p>
    Our Views have strongly defined <b>interfaces</b>. This is one of the requirements of an MVP implementation that helps achieve loose coupling between a View and a Presenter. 
    We now have the flexibility to later choose to use a different View as long as it implements the required interface, or multiple Presenters could use the original View.<br />
    <br />
    In the <b>Mindscape.BackgroundMotion.Website.Views.IViewView</b> interface we define this contract:
    </p>
    
    <br />
    <div style="font-family: Consolas; font-size: 11pt; color: black; background: white;">
    <p style="margin: 0px;">&nbsp; <span style="color: blue;">public</span> <span style="color: blue;">interface</span> <span style="color: navy; font-weight: bold;">IViewView</span> : <span style="color: navy; font-weight: bold;">IView</span></p>
    <p style="margin: 0px;">&nbsp; {</p>
    <p style="margin: 0px;">&nbsp; &nbsp; <span style="color: gray;">///</span><span style="color: green;"> </span><span style="color: gray;">&lt;summary&gt;</span></p>
    <p style="margin: 0px;">&nbsp; &nbsp; <span style="color: gray;">///</span><span style="color: green;"> The contribution which has been requested</span></p>
    <p style="margin: 0px;">&nbsp; &nbsp; <span style="color: gray;">///</span><span style="color: green;"> </span><span style="color: gray;">&lt;/summary&gt;</span></p>
    <p style="margin: 0px;">&nbsp; &nbsp; <span style="color: navy; font-weight: bold;">Contribution</span> Contribution { <span style="color: blue;">get</span>; <span style="color: blue;">set</span>; }</p>
    </div>
    <br />
    
    <p>
    Notice how the view expects to be assigned a Contribution object from our domain model which will scope what it will render out.<br />
    </p>
        
    <br />
    <div align="center">
        <img border="0" src="/Images/Dev/MVPc.jpg" /><br />
        <p>The <b>Presenter</b> loads the required <b>Model</b> and populates the <b>View</b></p>    
    </div>
    <br />
    
    <p>
    The Presenter assigns the Contribution we asked for by assigning a value to the .Contribution property on the View.
    </p>
    
    <div style="font-family: Consolas; font-size: 11pt; color: black; background: white;">
    <p style="margin: 0px;">&nbsp; &nbsp; <span style="color: navy; font-weight: bold;">Contribution</span> contribution;</p>
    <p style="margin: 0px;"></p>
    <p style="margin: 0px;">&nbsp; &nbsp; <span style="color: blue;">if</span> (<span style="color: blue;">null</span> != (contribution = Controller.ViewContribution(id.Value)))</p>
    <p style="margin: 0px;">&nbsp; &nbsp; {</p>
    <p style="margin: 0px;">&nbsp; &nbsp; &nbsp; View.Preview = ParsePreviewLink(contribution);</p>
    <p style="margin: 0px;">&nbsp; &nbsp; &nbsp; <b><span style="color: Red">View.Contribution = contribution;</span></b></p>
    <p style="margin: 0px;">&nbsp; &nbsp; }</p>
    <p style="margin: 0px;">&nbsp; &nbsp; <span style="color: blue;">else</span></p>
    <p style="margin: 0px;">&nbsp; &nbsp; &nbsp; {</p>
    <p style="margin: 0px;">&nbsp; &nbsp; &nbsp; &nbsp; Controller.RedirectTo(<span style="color: maroon;">"~"</span>);</p>
    <p style="margin: 0px;">&nbsp; &nbsp; &nbsp; }</p>
    </div>
    
    <br />
    <br />
    
    <h2>Resources</h2>
    
    <ul>
        <li>Martin Fowler on the <a href="http://www.martinfowler.com/eaaDev/SupervisingPresenter.html">Supervising Controller</a> and <a href="http://www.martinfowler.com/eaaDev/PassiveScreen.html">Passive View</a> patterns</li>
        <li>Phil Haack <a href="http://haacked.com/archive/2006/08/09/ASP.NETSupervisingControllerModelViewPresenterFromSchematicToUnitTestsToCode.aspx">describes how to implement Model View Presenter</a> in ASP.NET</li>
    </ul>
    
</asp:Content>
